''' <summary>
''' Decode XML created by StoretResult web service, getResults routine
''' </summary>
''' <remarks></remarks>
Public Class clsDataStoretXML
    Inherits clsData
    Implements IDisposable

    Private mDataSet As New DataSet
    Private mDataTable As New DataTable 'flat-file table
    Private mNumRecords As Integer

    ''' <summary>
    ''' Instantiate clsData, assign filename, open file, set filelength and fieldnames
    ''' </summary>
    ''' <param name="_Filename">Name of text file to read</param>
    Public Overrides Sub Initialize(ByVal _Filename As String)
        MyBase.Initialize(_Filename)
        mDataType = enumDataType.StoretStaXML

        mFieldNames.Add("Agency")
        mFieldNames.Add("Date_Time")
        mFieldNames.Add("Station_ID")
        mFieldNames.Add("Station_Name")
        mFieldNames.Add("PCode")
        mFieldNames.Add("RCode")
        mFieldNames.Add("Result")
        mFieldNames.Add("Units")
        mFieldNames.Add("Depth_M")

        For Each s As String In mFieldNames
            mDataTable.Columns.Add(s, GetType(String))
        Next

        Using fs = New IO.FileStream(mFilename, IO.FileMode.Open)
            Dim mode As Data.XmlReadMode = mDataSet.ReadXml(fs)
            If mDataSet.Tables.Count > 0 Then
                'must crawl through relations to gather up all data in dataset, converting hierachical dataset into flat data file for import
                For Each drOrganization As Data.DataRow In mDataSet.Tables("Organization").Rows
                    Dim Agency As String = TestNull(drOrganization.GetChildRows(mDataSet.Relations("Organization_OrganizationDescription"))(0).Item("OrganizationIdentifier"), "")
                    Agency = Agency.Trim
                    For Each drActivity As DataRow In drOrganization.GetChildRows(mDataSet.Relations("Organization_Activity")) 'has activity_id and organization_id, no other useful data
                        Dim DateTime As String = TestNull(drActivity.GetChildRows(mDataSet.Relations("Activity_ActivityDescription"))(0).Item("ActivityStartDate"), "") & " " &
                                                 TestNull(drActivity.GetChildRows(mDataSet.Relations("Activity_ActivityDescription"))(0).Item("ActivityStartTime"), "")

                        'Dim DateTime As String = TestNull(drActivity.GetChildRows(mDataSet.Relations("Activity_ActivityDescription"))(0).Item("ActivityStartDate"), "")
                        Dim drActivityLocation As DataRow = drActivity.GetChildRows(mDataSet.Relations("Activity_ActivityLocation"))(0)
                        Dim ReferenceText As String = TestNull(drActivityLocation.Item("ActivityDepthAltitudeReferencePointText"), "")
                        Dim drActivityDepthHeightMeasure As DataRow = drActivityLocation.GetChildRows(mDataSet.Relations("ActivityLocation_ActivityDepthHeightMeasure"))(0)
                        Dim Depth As String = TestNull(drActivityDepthHeightMeasure.Item("MeasureValue"), "")
                        Dim DepthUnits As String = TestNull(drActivityDepthHeightMeasure.Item("MeasureUnitCode"), "")
                        Dim drActivityMonitoringLocation As DataRow = drActivity.GetChildRows(mDataSet.Relations("Activity_MonitoringLocation"))(0)
                        Dim StationID As String = Agency & ":" & TestNull(drActivityMonitoringLocation.Item("MonitoringLocationIdentifier"), "")
                        Dim StationName As String = ""
                        If drActivityMonitoringLocation.Table.Columns.Contains("MonitoringLocationName") Then StationName = TestNull(drActivityMonitoringLocation.Item("MonitoringLocationName"), "")
                        'convert depth values to meters
                        If Depth <> "" And DepthUnits.ToUpper = "FT" Then Depth = Val(Depth) * 0.3048
                        If ReferenceText.ToUpper <> "SURFACE" Then Depth = ""
                        For Each drResult As DataRow In drActivity.GetChildRows(mDataSet.Relations("Activity_Result"))
                            Dim RCode As String = ""
                            If mDataSet.Tables.Contains("ResultLabInformation") And mDataSet.Tables.Contains("ResultDetectionQuantitationLimit") Then
                                For Each drResultLabInformation As DataRow In drResult.GetChildRows("Result_ResultLabInformation")
                                    For Each drResultDetectionQuantitationLimit As DataRow In drResultLabInformation.GetChildRows("ResultLabInformation_ResultdetectionQuantitationLimit")
                                        RCode = TestNull(drResultDetectionQuantitationLimit("DetectionQuantitationLimitTypeName"), "")
                                    Next
                                Next
                            End If
                            For Each drResultDescription As DataRow In drResult.GetChildRows(mDataSet.Relations("Result_ResultDescription"))
                                Dim CharName As String = TestNull(drResultDescription.Item("CharacteristicName"), "")
                                For Each drResultMeasure As DataRow In drResultDescription.GetChildRows(mDataSet.Relations("ResultDescription_ResultMeasure"))
                                    Dim Result As String = TestNull(drResultMeasure.Item("ResultMeasureValue"), "")
                                    RCode = TestNull(drResultMeasure.Item("ResultMeasureQualifierCode"), RCode)
                                    Dim SampFrac As String = ""
                                    If drResultMeasure.Table.Columns.IndexOf("ResultSampleFractionText") <> -1 Then
                                        SampFrac = TestNull(drResultDescription.Item("ResultSampleFractionText"), "")
                                    End If
                                    Dim Units As String = TestNull(drResultMeasure.Item("MeasureUnitCode"), "")
                                    'note: calling routine probably should concatenate stationID with agency like 012345+112WRD
                                    'note: calling routine will need to replace STORET long characteristic/sample fraction/unit names with pcodes
                                    Dim PCode As String = CharName.Trim & ";" & SampFrac.Trim & ";" & Units.Trim

                                    'following interpretation is a guess based on observed data; really there should be a MeasureQualifierCode
                                    If RCode.StartsWith("Lower") Or RCode.Contains("Detection") Or RCode.StartsWith("Not Detected") Then
                                        RCode = "<"
                                    ElseIf RCode.StartsWith("Upper") Then
                                        RCode = ">"
                                    ElseIf RCode <> "" Then
                                        RCode = RCode.Substring(0, 1)
                                    End If
                                    If RCode <> "" OrElse (Result <> "" AndAlso IsNumeric(Result)) Then
                                        mDataTable.Rows.Add(Agency.Trim, DateTime, StationID.Trim, StationName.Trim, PCode, RCode, Result, Units.Trim, Depth.Trim)
                                    End If
                                Next
                            Next
                        Next
                    Next
                Next
            End If
        End Using
        mNumRecords = mDataTable.Rows.Count
        mActiveTable = IO.Path.GetFileNameWithoutExtension(mFilename)
        mTableNames.Add(mActiveTable)
        ActiveTable = mActiveTable 'to force it to get the fieldnames
    End Sub

    ''' <summary>
    ''' Read next line from file into memory, storing into mItems array
    ''' Also save mLastLineRead for error reporting
    ''' </summary>
    ''' <returns>True if successful, false if eof reached and no more data</returns>
    Public Overrides Function Read() As Boolean
        Try
            If Not MyBase.Read() Or mDataTable.Rows.Count = 0 Then Return False
            mItems.Clear()
            For c As Integer = 0 To mDataTable.Columns.Count - 1
                mItems.Add(mDataTable.Rows(mRecordNum).Item(c))
            Next
            Return mRecordNum < mDataTable.Rows.Count - 1
        Catch ex As Exception
            ErrorMsg(, ex)
            Return False
        End Try
    End Function

    ''' <summary>
    ''' Determine percent of file that has been read
    ''' </summary>
    ''' <returns>Percent of file read</returns>
    Public Overrides Function PercentComplete() As Double
        Return mRecordNum * 100.0 / (mNumRecords - 1)
    End Function

    Private disposed As Boolean = False

    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposed Then
            If disposing Then
                mDataTable.Dispose()
                mDataSet.Dispose()
            End If
        End If
        Me.disposed = True
    End Sub


End Class
